﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace TouchDriver
{
    class Vector2
    {
        public double _x;
        public double _y;
        public Vector2()
        {
            _x = 0; _y = 0;
        }

        public Vector2(double x, double y)
        {
            _x = x; _y = y;
        }
    }
    class DataProcess
    {
        public StreamReader pointInfo = new StreamReader("point_info.txt");
        public StreamReader specialPointInfo = new StreamReader("special_point_info.txt");
        public Dictionary<Vector2, Vector2> pointInfoMap = new Dictionary<Vector2, Vector2>();
        public Dictionary<Vector2, Vector2> specialPointInfoMap = new Dictionary<Vector2, Vector2>();
        public DataProcess()
        {
            while (!pointInfo.EndOfStream)
            {
                string temp = pointInfo.ReadLine();
                string[] text = new string[4];
                text = temp.Split('\t');
                Vector2 key = new Vector2(Convert.ToInt32(text[0]), Convert.ToInt32(text[1]));
                Vector2 value = new Vector2(Convert.ToInt32(text[2]), Convert.ToInt32(text[3]));
                pointInfoMap.Add(key, value);
            }
            while (!specialPointInfo.EndOfStream)
            {
                string temp = specialPointInfo.ReadLine();
                string[] text = new string[4];
                text = temp.Split('\t');
                Vector2 key = new Vector2(Convert.ToInt32(text[0]), Convert.ToInt32(text[1]));
                Vector2 value = new Vector2(Convert.ToInt32(text[2]), Convert.ToInt32(text[3]));
                specialPointInfoMap.Add(key, value);
            }
        }
        public Vector2 GetPosition(double x, double y)
        {
            return GetPosition(new Vector2(x, y));
        }
        public Vector2 GetPosition(Vector2 value)
        {
            Vector2 result = new Vector2();

            Vector2 minVector = new Vector2();
            Vector2 secondVector = new Vector2();
            double minDiff = 10000000;
            double secondDiff = 10000000;
            foreach (KeyValuePair<Vector2, Vector2> element in pointInfoMap)
            {
                double curDiff = (element.Value._x - value._x) * (element.Value._x - value._x) + (element.Value._y - value._y) * (element.Value._y - value._y);
                if (curDiff < minDiff)
                {
                    secondVector = minVector;
                    minVector = element.Key;
                    secondDiff = minDiff;
                    minDiff = curDiff;
                }
                else if (curDiff < secondDiff)
                {
                    secondVector = element.Key;
                    secondDiff = curDiff;
                }
            }
            bool isSpecial = false;
            foreach (KeyValuePair<Vector2, Vector2> element in specialPointInfoMap)
            {
                double curDiff = (element.Value._x - value._x) * (element.Value._x - value._x) + (element.Value._y - value._y) * (element.Value._y - value._y);
                if (curDiff < minDiff)
                {
                    minVector = element.Key;
                    minDiff = curDiff;
                    isSpecial = true;
                }
            }
            if (minDiff > 10000 * 10000)
                return new Vector2(0, 0);
            if (isSpecial)
                return minVector;
            result._x = (double)minDiff / (minDiff + secondDiff) * secondVector._x + (double)secondDiff / (minDiff + secondDiff) * minVector._x;
            result._y = (double)minDiff / (minDiff + secondDiff) * secondVector._y + (double)secondDiff / (minDiff + secondDiff) * minVector._y;
            //Vector2 beginValue = pointInfoMap[minVector];
            //Vector2 endValue = pointInfoMap[secondVector];
            //double rate1 = (double)(value._x - beginValue._x) / (endValue._x - beginValue._x);
            //double rate2 = (double)(value._y - beginValue._y) / (endValue._y - beginValue._y);
            //result._x = minVector._x + (secondVector._x - minVector._x) * (rate1+rate2)/2;
            //result._y = minVector._y + (secondVector._y - minVector._y) * (rate1+rate2)/2;
            return result;
            //return minVector;
            //return result;
        }

        //public Vector2 GetPosition2(Vector2 value)
        //{
        //    Vector2 result = new Vector2();

        //    Vector2 minVector = new Vector2();
        //    double minDiff = 10000000;
        //    foreach (KeyValuePair<Vector2, Vector2> element in pointInfoMap)
        //    {
        //        double curDiff = (element.Value._x - value._x) * (element.Value._x - value._x) + (element.Value._y - value._y) * (element.Value._y - value._y);
        //        if (curDiff < minDiff)
        //        {
        //           minVector = element.Key;
        //            minDiff = curDiff;
        //        }    
        //    }
        //    bool isSpecial = false;
        //    foreach (KeyValuePair<Vector2, Vector2> element in specialPointInfoMap)
        //    {
        //        double curDiff = (element.Value._x - value._x) * (element.Value._x - value._x) + (element.Value._y - value._y) * (element.Value._y - value._y);
        //        if (curDiff < minDiff)
        //        {
        //            minVector = element.Key;
        //            minDiff = curDiff;
        //            isSpecial = true;
        //        }
        //    }
        //    if (isSpecial)
        //        return minVector;
        //    Vector2 secondVector;
        //    Vector2 beginValue = pointInfoMap[minVector];
        //    if(beginValue._x < value._x)
        //    Vector2 endValue = pointInfoMap[secondVector];
        //    double rate1 = (double)(value._x - beginValue._x) / (endValue._x - beginValue._x);
        //    double rate2 = (double)(value._y - beginValue._y) / (endValue._y - beginValue._y);
        //    result._x = minVector._x + (secondVector._x - minVector._x) * (rate1 + rate2) / 2;
        //    result._y = minVector._y + (secondVector._y - minVector._y) * (rate1 + rate2) / 2;
        //    return result;
        //}

        Vector2 Search(Vector2 vec)
        {
            Vector2 result;
            if (pointInfoMap.TryGetValue(vec, out result))
                return result;
            else if (specialPointInfoMap.TryGetValue(vec, out result))
                return result;
            return new Vector2(0, 0);
        }
    }
}
